//
//  NSMutableArray+ZXAvoidCrash.m
//  MerchantBusinessClient
//
//  Created by simon on 2020/9/2.
//  Copyright © 2020 com.Chs. All rights reserved.
//

#import "NSMutableArray+ZXAvoidCrash.h"
#import "ZXAvoidCrashRuntime.h"
#import "ZXAvoidCrashReport.h"

@implementation NSMutableArray (ZXAvoidCrash)

+ (void)zx_avoidCrashExchangeMethod{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        Class __NSArrayM = NSClassFromString(@"__NSArrayM");

        //objectAtIndex:
    
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSArrayM originalSelector:@selector(objectAtIndex:) swizzledSelector:@selector(zx_avoidCrashObjectAtIndex:)];
        
        //objectAtIndexedSubscript:
        
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSArrayM originalSelector:@selector(objectAtIndexedSubscript:) swizzledSelector:@selector(zx_avoidCrashObjectAtIndexedSubscript:)];
        
        //addObject:
        //insertObject:atIndex:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSArrayM originalSelector:@selector(insertObject:atIndex:) swizzledSelector:@selector(zx_avoidCrashInsertObject:atIndex:)];
        
        //insertObjects: atIndexes:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:[NSMutableArray class] originalSelector:@selector(insertObjects:atIndexes:) swizzledSelector:@selector(zx_avoidCrashInsertObjects:atIndexes:)];
        
        
        //removeObjectsInRange:/removeObjectAtIndex:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:__NSArrayM originalSelector:@selector(removeObjectsInRange:) swizzledSelector:@selector(zx_avoidCrashRemoveObjectsInRange:)];
        
        //removeObjectsAtIndexes:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:[NSMutableArray class] originalSelector:@selector(removeObjectsAtIndexes:) swizzledSelector:@selector(zx_avoidCrashRemoveObjectsAtIndexes:)];
        
        //removeObject:inRange:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:[NSMutableArray class] originalSelector:@selector(removeObject:inRange:) swizzledSelector:@selector(zx_avoidCrashRemoveObject:inRange:)];
        
        //removeObjectIdenticalTo:inRange:
        [ZXAvoidCrashRuntime exchangeInstanceMethodWithClass:[NSMutableArray class] originalSelector:@selector(removeObjectIdenticalTo:inRange:) swizzledSelector:@selector(zx_avoidCrashRemoveObjectIdenticalTo:inRange:)];


    });
}



#pragma mark- 查询

#pragma mark -objectAtIndex:

//=================================================================
//                           objectAtIndex:
//=================================================================
//异常1:Trapped uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

- (id)zx_avoidCrashObjectAtIndex:(NSUInteger)index
{
    id object = nil;
    @try {
        object = [self zx_avoidCrashObjectAtIndex:index];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_returnNil];
    }
    @finally {
        return object;
    }
}



#pragma mark -objectAtIndexedSubscript:
//=================================================================
//             - (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx
//=================================================================
//异常1:NSRangeException;reason=*** -[__NSArrayM objectAtIndexedSubscript:]: index 2 beyond bounds [0 .. 0]
- (id)zx_avoidCrashObjectAtIndexedSubscript:(NSUInteger)index
{
    id object = nil;
    @try {
        object = [self zx_avoidCrashObjectAtIndexedSubscript:index];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_returnNil];
    }
    @finally {
        return object;
    }
}

#pragma mark- 增加

#pragma mark -insertObject:atIndex:

//=================================================================
//                addObject:
//                insertObject:atIndex:
//=================================================================
//异常1:Trapped uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
//异常2:Trapped uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM insertObject:atIndex:]: index 1 beyond bounds for empty array'

- (void)zx_avoidCrashInsertObject:(id)anObject atIndex:(NSUInteger)index {
    @try {
        [self zx_avoidCrashInsertObject:anObject atIndex:index];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
        
    }
}


#pragma mark -insertObjects: atIndexes:

//=================================================================
//               insertObjects: atIndexes:
//=================================================================

//异常1:Trapped uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray insertObjects:atIndexes:]: index 2 in index set beyond bounds [0 .. 1]'
//异常2:objects空或indexes空异常
//name = NSInvalidArgumentException;reason=*** -[NSMutableArray insertObjects:atIndexes:]: index set cannot be nil 
- (void)zx_avoidCrashInsertObjects:(NSArray*)objects atIndexes:(NSIndexSet *)indexes
{
    @try {
        [self zx_avoidCrashInsertObjects:objects atIndexes:indexes];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
        
    }
}


#pragma mark- 删除
#pragma mark -removeObjectAtIndex:删除某个对象；会调用removeObjectsInRange
#pragma mark - removeObjectsInRange:删除某组范围的对象：
//=================================================================
//           removeObjectAtIndex: //删除某个对象
//           removeObjectsInRange: //删除某组对象
//=================================================================
//异常1:name = NSRangeException;reason=*** -[__NSArrayM removeObjectsInRange:]: range {1, 1} extends beyond bounds for empty array
- (void)zx_avoidCrashRemoveObjectsInRange:(NSRange)range
{
    @try {
        [self zx_avoidCrashRemoveObjectsInRange:range];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
        
    }
}


#pragma mark -removeObjectsAtIndexes:删除某组索引的对象：
//=================================================================
//   - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes
//=================================================================
//异常1:Trapped uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray removeObjectsAtIndexes:]: index 1 in index set beyond bounds for empty array'
- (void)zx_avoidCrashRemoveObjectsAtIndexes:(NSIndexSet *)indexes
{
    @try {
        [self zx_avoidCrashRemoveObjectsAtIndexes:indexes];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
    
    }
}


#pragma mark -removeObject:inRange: 通过使用isEqual:方法进行对象比较(哈希值比较)确定删除所有匹配项
//=================================================================
//   removeObject:(ObjectType)anObject inRange:(NSRange)range
//=================================================================
//异常1:Trapped uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray removeObject:inRange:]: range {0, 5} extends beyond bounds [0 .. 0]'
- (void)zx_avoidCrashRemoveObject:(id)anObject inRange:(NSRange)range
{
    @try {
        [self zx_avoidCrashRemoveObject:anObject inRange:range];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
    }
}

#pragma mark -removeObjectIdenticalTo:inRange: 通过对象的地址比较（物理地址比较）来确定删除所有匹配项；
//=================================================================
//   removeObjectIdenticalTo:(ObjectType)anObject inRange:(NSRange)range
//=================================================================
//异常1:Trapped uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray removeObject:inRange:]: range {0, 5} extends beyond bounds [0 .. 0]'
- (void)zx_avoidCrashRemoveObjectIdenticalTo:(id)anObject inRange:(NSRange)range
{
    @try {
        [self zx_avoidCrashRemoveObject:anObject inRange:range];
    }
    @catch (NSException *exception) {
        [ZXAvoidCrashReport crashReportWithException:exception avoidCrashHandleType:AvoidCrashHandleType_doNothing];
    }
    @finally {
        
    }
}


@end
